﻿using System;
using System.Threading;

namespace HslCommunication.Core
{
	/// <summary>
	/// 一个高级的混合线程同步锁，采用了基元用户加基元内核同步构造实现，并包含了自旋和线程所有权
	/// </summary>
	/// <remarks>
	/// 当竞争的频率很高的时候，锁的时间很短的时候，当前的锁可以获得最大性能。
	/// </remarks>
	// Token: 0x02000121 RID: 289
	internal sealed class AdvancedHybirdLock : IDisposable
	{
		// Token: 0x060018B8 RID: 6328 RVA: 0x0007DBD0 File Offset: 0x0007BDD0
		private void Dispose(bool disposing)
		{
			bool flag = !this.disposedValue;
			if (flag)
			{
				if (disposing)
				{
				}
				this.m_waiterLock.Value.Close();
				this.disposedValue = true;
			}
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		// Token: 0x060018B9 RID: 6329 RVA: 0x0007DC0C File Offset: 0x0007BE0C
		public void Dispose()
		{
			this.Dispose(true);
		}

		/// <summary>
		/// 自旋锁的自旋周期，当竞争频率小，就要设置小，当竞争频率大，就要设置大，锁时间长就设置小，锁时间短就设置大，这样才能达到真正的高性能，默认为1000
		/// </summary>
		// Token: 0x17000538 RID: 1336
		// (get) Token: 0x060018BA RID: 6330 RVA: 0x0007DC17 File Offset: 0x0007BE17
		// (set) Token: 0x060018BB RID: 6331 RVA: 0x0007DC1F File Offset: 0x0007BE1F
		public int SpinCount
		{
			get
			{
				return this.m_spincount;
			}
			set
			{
				this.m_spincount = value;
			}
		}

		/// <summary>
		/// 获取锁
		/// </summary>
		// Token: 0x060018BC RID: 6332 RVA: 0x0007DC2C File Offset: 0x0007BE2C
		public void Enter()
		{
			int managedThreadId = Thread.CurrentThread.ManagedThreadId;
			bool flag = managedThreadId == this.m_owningThreadId;
			if (flag)
			{
				this.m_recursion++;
			}
			else
			{
				SpinWait spinWait = default(SpinWait);
				for (int i = 0; i < this.m_spincount; i++)
				{
					bool flag2 = Interlocked.CompareExchange(ref this.m_waiters, 1, 0) == 0;
					if (flag2)
					{
						this.m_owningThreadId = Thread.CurrentThread.ManagedThreadId;
						this.m_recursion = 1;
						return;
					}
					spinWait.SpinOnce();
				}
				bool flag3 = Interlocked.Increment(ref this.m_waiters) > 1;
				if (flag3)
				{
					this.m_waiterLock.Value.WaitOne();
				}
				this.m_owningThreadId = Thread.CurrentThread.ManagedThreadId;
				this.m_recursion = 1;
			}
		}

		/// <summary>
		/// 离开锁
		/// </summary>
		// Token: 0x060018BD RID: 6333 RVA: 0x0007DCFC File Offset: 0x0007BEFC
		public void Leave()
		{
			bool flag = Thread.CurrentThread.ManagedThreadId != this.m_owningThreadId;
			if (flag)
			{
				throw new SynchronizationLockException("Current Thread have not the owning thread.");
			}
			int num = this.m_recursion - 1;
			this.m_recursion = num;
			bool flag2 = num > 0;
			if (!flag2)
			{
				this.m_owningThreadId = 0;
				bool flag3 = Interlocked.Decrement(ref this.m_waiters) == 0;
				if (!flag3)
				{
					this.m_waiterLock.Value.Set();
				}
			}
		}

		// Token: 0x04000591 RID: 1425
		private bool disposedValue = false;

		// Token: 0x04000592 RID: 1426
		private int m_waiters = 0;

		// Token: 0x04000593 RID: 1427
		private readonly Lazy<AutoResetEvent> m_waiterLock = new Lazy<AutoResetEvent>(() => new AutoResetEvent(false));

		// Token: 0x04000594 RID: 1428
		private int m_spincount = 1000;

		// Token: 0x04000595 RID: 1429
		private int m_owningThreadId = 0;

		// Token: 0x04000596 RID: 1430
		private int m_recursion = 0;
	}
}
